package com.ds.infra.ibatis.demo.service;

import com.ds.infra.ibatis.demo.mapper.AccountMapper;
import com.ds.infra.ibatis.demo.model.Account;
import com.ds.infra.ibatis.transaction.annotation.Isolation;
import com.ds.infra.ibatis.transaction.annotation.Propagation;
import com.ds.infra.ibatis.transaction.annotation.Transactional;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class AccountService {

    private final AccountMapper accountMapper;

    @Transactional
    public void transfer(Long fromId, Long toId, Double amount) {
        Account from = accountMapper.selectById(fromId);
        Account to = accountMapper.selectById(toId);

        if (from.getBalance() < amount) {
            throw new RuntimeException("Insufficient balance");
        }

        accountMapper.updateBalance(fromId, from.getBalance() - amount);
        accountMapper.updateBalance(toId, to.getBalance() + amount);
    }

    @Transactional(isolation = Isolation.READ_COMMITTED)
    public Double getBalance(Long accountId) {
        return accountMapper.selectById(accountId).getBalance();
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void createAccount(Account account) {
        accountMapper.insert(account);
    }
}
